/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.search.scanners; import java.io.*; import java.text.MessageFormat; import java.util.*; import org.openide.*; import org.openide.nodes.*; import org.openide.loaders.*; import org.openide.filesystems.*; import org.openide.util.enum.*; import org.openidex.search.*; import org.netbeans.modules.search.types.*; import org.netbeans.modules.search.*; import org.netbeans.modules.search.res.Res; /** * Scanner that can scan all collection nodes in repository. * It tests DataObjectType by test(DataObject). * * @author Petr Kuzel * @version 1.0 */ public class RepositoryScanner extends Scanner { /** DataObjectTypes to be applied */ private Vector dot; private DataObjectType[] criteria; //trace the code private boolean TRACE = false; //cache of file objects to skip //due they were recognized private HashSet cache; /** Creates new RepositoryScanner */ public RepositoryScanner() { dot = new Vector(); cache = new HashSet(); } /** Add new search type. The type will be applied on * scanned object if all other such added types are eveluated to true. */ public void add(SearchType type) { t("add(" + type + ")"); // NOI18N if (type instanceof DataObjectType) { dot.add(type); } else { throw new ClassCastException("Unsupported search type"); // NOI18N } } /** Scan particular nodes. Test if their children * match added() search types. */ public void scan(Node[] nodes) { t("scan()"); // NOI18N try { criteria = new DataObjectType[dot.size()]; dot.copyInto(criteria); nodes = normalizeNodes(nodes); // test whether scan whole repository if (nodes.length == 1) { if ( nodes[0].getCookie(org.openide.filesystems.Repository.class) != null) { scanRepository(); return; } } for (int i = 0; i<nodes.length; i++) { Node.Cookie cake = nodes[i].getCookie(org.openide.loaders.DataFolder.class); if ( cake != null) { DataFolder folder = (DataFolder) cake; scan(folder.getPrimaryFile()); } } } catch ( InterruptedException ex) { // finnish scanning t("interrupted."); // NOI18N } } /** * Scan all visible filesystems. */ private void scanRepository() throws InterruptedException { Repository rep = TopManager.getDefault().getRepository(); Enumeration fss = rep.getFileSystems(); while (fss.hasMoreElements()) { org.openide.filesystems.FileSystem fs = (org.openide.filesystems.FileSystem)fss.nextElement(); if (fs.isValid() && !fs.isHidden()) scan(fs.getRoot()); } } /** * Scan recursively particular FileObject. * Fires found notifications. */ private void scan(FileObject fo) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); if (fo.isData()) { //leaf t("scanning " + fo); // NOI18N DataObject dobj = getDataObject(fo); if (dobj == null) return; SearchDetail detail = new SearchDetail(); // test obtained object on all criteria for (int i = 0; i<criteria.length; i++) { if ( ! criteria[i].test(dobj, detail) ) return; } Node node = dobj.getNodeDelegate(); t("Found node: "+ node); // NOI18N if (node != null) { // mark with detail cookie notifyFound( new Node[] { new FoundNode (node, detail.isEmpty () ? null : detail) } ); } return; } else { //data folder FileObject[] fos = fo.getChildren(); if (fos.length == 0) return; for(int i=0; i<fos.length; i++) scan(fos[i]); } } // // caching model: cache holds recognized DataObjects // private boolean cacheHit(DataObject dobj) { return cache.contains(dobj); } private void cacheAdd(DataObject dobj) { cache.add(dobj); } /** * translates FileObject to DataObject. * @return DataObject or null if it was already recognized */ private DataObject getDataObject(FileObject fo) { DataObject dobj = null; try { try { dobj = org.openide.loaders.DataObject.find(fo); } catch (DataObjectNotFoundException ex1) { t("Creating dobj from scratch"); // NOI18N dobj = TopManager.getDefault().getLoaderPool().findDataObject(fo); } if (cacheHit(dobj)) { return null; } else { cacheAdd(dobj); } } catch (DataObjectExistsException ex) { throw new RuntimeException("Should not occur."); // NOI18N } catch (IOException ex) { if (Boolean.getBoolean ("netbeans.debug.exceptions")) // NOI18N ex.printStackTrace(); } return dobj; } /** remove kids from set */ private Node[] normalizeNodes(Node[] nodes) { Vector ret = new Vector(); for (int i = 0; i<nodes.length; i++) { if (! hasParent(nodes[i],nodes)) ret.add(nodes[i]); } Node[] newNodes = new Node[ret.size()]; ret.copyInto(newNodes); return newNodes; } private boolean hasParent(Node node, Node[] nodes) { for (Node parent = node.getParentNode(); parent != null; parent = parent.getParentNode()) { for (int i = 0; i<nodes.length; i++) { if (nodes[i].equals(parent)) return true; } } return false; } /** The name given to my thread. */ public String toString() { return "RepositoryScanner"; // NOI18N } /** FOr debugging pusposes only. */ private void t(String msg) { if (TRACE) System.err.println("RepositoryScanner: " + msg); } /** Node that may know search result details. */ private static class FoundNode extends FilterNode { private DetailCookie detail; public FoundNode(Node original, DetailCookie detail) { super(original); this.detail = detail; DataObject obj = (DataObject) original.getCookie (DataObject.class); if (obj != null) { FileObject folder = obj.getPrimaryFile ().getParent (); if (folder != null) { String pkg = folder.getPackageName ('.'); String hint; if (pkg.equals ("")) // NOI18N hint = Res.hint ("result_default_package"); // NOI18N else hint = MessageFormat.format (Res.hint ("result_package"), // NOI18N new Object[] { pkg }); //System.err.println("will set to: " + hint); disableDelegation (DELEGATE_SET_SHORT_DESCRIPTION | DELEGATE_GET_SHORT_DESCRIPTION); setShortDescription (hint); } } } public Node.Cookie getCookie(Class type) { if (type.equals(DetailCookie.class) && detail != null) return detail; return super.getCookie(type); } } } /* * Log * 6 Gandalf 1.5 1/16/00 Jesse Glick Tooltips with package on * search result nodes. * 5 Gandalf 1.4 1/13/00 Radko Najman I18N * 4 Gandalf 1.3 1/11/00 Petr Kuzel Result details added. * 3 Gandalf 1.2 1/5/00 Petr Kuzel Margins used. Help * contexts. * 2 Gandalf 1.1 12/15/99 Martin Balin Fixed package name * 1 Gandalf 1.0 12/14/99 Petr Kuzel * $ */